package me.magicall.db.springjdbc.tmp;


//public class SpringJdbcTableMetaAccessor implements TableMetaAccessor, Cached {
//
//	protected static final Pattern FOREIGN_KEY_PATTERN = Pattern.compile(//
//			"^\\s*`?([\\w_]+)`?+\\s+" + //
//					"FOREIGN KEY\\s*\\(`?([\\w_]+)`?\\)\\s*" + //
//					"REFERENCES\\s+`?([\\w_]+)`?\\s+\\(`?([\\w_]+)`?\\).*$", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
//	private DBMS dbms = CommonDBMS.MYSQL;
//
//	private NamedParameterJdbcOperations jdbc;
//
//	private final ConcurrentHashMap<String, TableMeta> tableMetaMap = new ConcurrentHashMap<String, TableMeta>();
//
//	public SpringJdbcTableMetaAccessor() {
//		super();
//	}
//
//	public SpringJdbcTableMetaAccessor(final NamedParameterJdbcOperations jdbc) {
//		super();
//		this.jdbc = jdbc;
//	}
//
//	public SpringJdbcTableMetaAccessor(final DataSource dataSource) {
//		jdbc = new NamedParameterJdbcTemplate(dataSource);
//	}
//
//	//==============================================
//	@Override
//	public TableMeta getTableMetaUsingModelName(final String modelName) {
//		return getTableMetaUsingTableName(DbUtil.javaNameToDbName(modelName));
//	}
//
//	@Override
//	public TableMeta getTableMetaUsingTableName(final String tableName) {
//		TableMeta tableMeta = tableMetaMap.get(tableName);
//		if (tableMeta == null) {
//			tableMeta = build(tableName);
//			tableMetaMap.putIfAbsent(tableName, tableMeta);
//		}
//		return tableMeta;
//	}
//
//	@Override
//	public TableMeta getTableMetaIgnoreCase(final String tableNameOrModelName) {
//		return getTableMetaUsingTableName(DbUtil.javaNameToDbName(tableNameOrModelName));
////		for (final Entry<String, TableMeta> e : tableMetaMap.entrySet()) {
////			final String s = e.getKey();
////			if (s.equalsIgnoreCase(tableNameOrModelName) || s.equalsIgnoreCase(DbUtil.javaNameToDbName(tableNameOrModelName))) {
////				return e.getValue();
////			}
////		}
////		return null;
//	}
//
//	protected TableMeta build(final String tableName) {
//		final TableMeta meta = new TableMeta(tableName);
//		//columns using describe table
//		final Map<String, DbColumn> columnMap = new HashMap<String, DbColumn>();
//		final List<Map<String, Object>> columnMetas = getJdbc().getJdbcOperations().queryForList("describe " + tableName);
//		for (final Map<String, Object> map : columnMetas) {
//			final DbColumn column = new DbColumn();
//			//name
//			final String name = (String) map.get("Field");
//			column.setName(name);
//			//type
//			final String typeString = (String) map.get("Type");
//			final boolean unsigned = typeString.contains("unsigned");
//			column.setUnsigned(unsigned);
//			final boolean zeroFill = typeString.contains("zerofill");
//			column.setZeroFill(zeroFill);
//			final String[] ss = typeString.split("\\s+");
//			final String s0 = ss[0];
//			final int index = s0.indexOf('(');
//			String typeName;
//			if (index >= 0) {
//				typeName = s0.substring(0, index);
//				final String lenStr = s0.substring(index + 1, s0.indexOf(')', index));
//				column.setLength(Kits.INT.fromString(lenStr));
//			} else {//some type doesn't have length, e.g timestamp
//				typeName = s0;
//			}
//			column.setType(getDbms().getType(typeName));
//			//nullable
//			final boolean nullable = !"NO".equals(map.get("Null"));
//			column.setNullable(nullable);
//			//default value
//			final String defValue = (String) map.get("Default");
//			column.setDefaultValue(defValue);
//			//auto increase
//			final String extra = (String) map.get("Extra");
//			final boolean autoInc = extra.contains("auto_increment");
//			column.setAutoInc(autoInc);
//
//			meta.add(column);
//			columnMap.put(name, column);
//		}
//		//keys
//		final Map<String, Key> keyMap = new HashMap<String, Key>();
//		final List<Map<String, Object>> indexMetas = getJdbc().getJdbcOperations().queryForList("show index from " + tableName);
//		for (final Map<String, Object> map : indexMetas) {
//			final String keyName = (String) map.get("Key_name");
//			final String columnName = (String) map.get("Column_name");
//			if ("PRIMARY".equals(keyName)) {
//				final Key key = new Key();
//				key.setType(KeyType.PRIMARY);
//				key.add(columnMap.get(columnName));
//				key.setName(keyName);
//
//				meta.setPrimaryKey(key);
//			} else {
//				Key key = keyMap.get(keyName);
//				if (key == null) {
//					key = new Key();
//					//key name
//					key.setName(keyName);
//					//key type
//					final Long nonUnique = (Long) map.get("Non_unique");
//					final boolean uniq = nonUnique == 0;
//					key.setType(uniq ? KeyType.UNIQUE : KeyType.COMMON);
//
//					key.add(columnMap.get(columnName));
//
//					meta.getKeys().add(key);
//					keyMap.put(keyName, key);
//				} else {
//					key.add(columnMap.get(columnName));
//				}
//			}
//		}
//		//foreign key.using 'show create table' statement
//		final String createTableSql = (String) getCreateTableSql(tableName).get(getDbms().getResultColumnNameOfShowCreateTable());
//		if (Kits.STR.containsIgnoreCase(createTableSql, "DEFINER VIEW")) {//it's a view
//			//SQL SECURITY DEFINER VIEW `article_summary` AS (
//			//	select `a`.`id` AS `id`,`a`.`name` AS `name`,`a`.`add_time` AS `add_time`,`a`.`up_time` AS `up_time`,`t`.`id` AS `tag_id`,`t`.`name` AS `tag_name`,`t`.`icon` AS `tag_img` 
//			//	from ((`article` `a` join `tag` `t`) join `tag_ref` `r`) 
//			//	where ((`r`.`item_id` = `a`.`id`) and (`r`.`tag_id` = `t`.`id`)))
//		} else {//it's a table
//			int constraintIndex = 0;
//			int beginIndex = 0;
//			while ((constraintIndex = createTableSql.indexOf("CONSTRAINT", beginIndex)) >= 0) {
//				beginIndex = constraintIndex + "CONSTRAINT".length();
//				final String substring = createTableSql.substring(beginIndex);
//				final Matcher matcher = FOREIGN_KEY_PATTERN.matcher(substring);
//				if (matcher.matches()) {
//					final String refedTableName = matcher.group(3);
//					if (refedTableName.equalsIgnoreCase(tableName)) {
//						continue;
//					}
//
//					final String foreignKeyName = matcher.group(1);
//					final String columnName = matcher.group(2);
//					final String refedColumnName = matcher.group(4);
//
//					final ForeignKey foreignKey = new ForeignKey();
//					foreignKey.setName(foreignKeyName);
//					foreignKey.setReferencingColumn(columnMap.get(columnName));
//					foreignKey.setReferencingTable(meta);
//
//					final TableMeta refedTable = getTableMetaUsingTableName(refedTableName);
//					foreignKey.setReferencedTable(refedTable);
//					for (final DbColumn column : refedTable.getColumns()) {
//						if (column.getName().equals(refedColumnName)) {
//							foreignKey.setReferencedColumn(column);
//							break;
//						}
//					}
//				}
//			}
//		}
//		return meta;
//	}
//
//	public DBMS getDbms() {
//		return dbms;
//	}
//
//	public void setDbms(final DBMS dbms) {
//		this.dbms = dbms;
//	}
//
//	public NamedParameterJdbcOperations getJdbc() {
//		return jdbc;
//	}
//
//	public void setJdbc(final NamedParameterJdbcOperations jdbc) {
//		this.jdbc = jdbc;
//	}
//
//	protected Map<String, Object> getCreateTableSql(final String tableName) {
//		return jdbc.getJdbcOperations().queryForMap("show create table " + tableName);
//	}
//
//	@Override
//	public void dropCache() {
//		tableMetaMap.clear();
//	}
//}
